# - 多进程锁, 多线程锁都要自己实现一遍
# - 多进程通过Queue来实现进程通信
# - 把上述概念熟记并理解
import time
from threading import Thread
from multiprocessing import Process, Lock, Queue

# 以下代码可使用with
# def save_to_file(index):
#     f = open("test.log", "w", encoding="utf-8")
#     f.write(index)
#     f.close()

# 进程间通信
# 多进程锁
def save_to_file(index, lock):
    # 拿锁
    # lock.acquire() 替换为上下文管理器：with lock
    with lock:
        with open("test.log", "a", encoding="utf-8") as f:
            f.write(str(index) + "\n")
    # 释放锁
    # lock.release()  替换为上下文管理器：with lock


if __name__ == "__main__":
    process_array = []
    lock = Lock()
    for i in range(10):
        p = Process(target=save_to_file, args=(i, lock))
        process_array.append(p)
        p.start()
    for p in process_array:
        p.join()
    print("done!!!!!")

# 多进程通过Queue来实现进程通信


def save_to_queue(index, my_queue):
    my_queue.put(index)
    print(my_queue.get())


if __name__ == "__main__":
    process_array2 = []
    my_queue = Queue()
    for i in range(10):
        p = Process(target=save_to_queue, args=(i, my_queue))
        process_array2.append(p)
        p.start()
    for p in process_array2:
        p.join()
    print("多进程通过Queue来实现进程通信:done!")

# 线程间通信/线程安全及GIL锁
zero = 0
# 加互斥锁
lock = Lock()


def foo():
    global zero
    for i in range(10**6):
        with lock:
            zero += 1
            zero -= 1

        # zero += 1
        # zero -= 1


if __name__ == "__main__":
    process_array3 = []
    for i in range(2):
        p = Thread(target=foo)
        process_array3.append(p)
        p.start()
    for p in process_array3:
        p.join()

    print("zero:", zero)